#include "gamedatapool.h"
#include <QDebug>
#include <QDateTime>

GameDataPool* GameDataPool::s_instance = nullptr;
QMutex GameDataPool::s_instanceMutex;

GameDataPool* GameDataPool::instance()
{
    QMutexLocker locker(&s_instanceMutex);
    if (!s_instance) {
        s_instance = new GameDataPool();
    }
    return s_instance;
}

void GameDataPool::destroyInstance()
{
    QMutexLocker locker(&s_instanceMutex);
    if (s_instance) {
        delete s_instance;
        s_instance = nullptr;
    }
}

GameDataPool::GameDataPool(QObject *parent)
    : QObject(parent)
    , m_cleanupTimer(new QTimer(this))
    , m_statsTimer(new QTimer(this))
{
    // 注册自定义类型
    qRegisterMetaType<GameDataPool::PoolStats>("GameDataPool::PoolStats");
    
    // 初始化统计信息
    m_stats = PoolStats();
    
    // 设置定时器
    m_cleanupTimer->setInterval(CLEANUP_INTERVAL);
    m_statsTimer->setInterval(STATS_INTERVAL);
    
    connect(m_cleanupTimer, &QTimer::timeout, this, &GameDataPool::onCleanupTimer);
    connect(m_statsTimer, &QTimer::timeout, this, &GameDataPool::onStatsTimer);
    
    // 初始化对象池
    initializePools();
    
    // 启动定时器
    m_cleanupTimer->start();
    m_statsTimer->start();
    
    qDebug() << "GameDataPool: 对象池已初始化";
}

GameDataPool::~GameDataPool()
{
    cleanupPools();
    qDebug() << "GameDataPool: 对象池已销毁";
}

void GameDataPool::initializePools()
{
    // 预分配游戏数据对象
    for (int i = 0; i < INITIAL_POOL_SIZE; ++i) {
        RenderReadyGameData* data = new RenderReadyGameData();
        m_gameDataPool.enqueue(data);
        m_stats.gameDataPoolSize++;
        m_stats.gameDataCreated++;
    }
    
    // 预分配点列表对象
    for (int i = 0; i < INITIAL_POOL_SIZE; ++i) {
        QList<QPoint>* list = new QList<QPoint>();
        list->reserve(50); // 预分配空间，避免频繁重新分配
        m_pointListPool.enqueue(list);
        m_stats.pointListPoolSize++;
        m_stats.pointListCreated++;
    }
    
    // 预分配JSON对象
    for (int i = 0; i < INITIAL_POOL_SIZE; ++i) {
        QJsonObject* obj = new QJsonObject();
        m_jsonObjectPool.enqueue(obj);
        m_stats.jsonObjectPoolSize++;
        m_stats.jsonObjectCreated++;
    }
    
    updateMemoryEstimate();
    
    qDebug() << "GameDataPool: 对象池初始化完成";
    qDebug() << "  游戏数据对象:" << m_stats.gameDataPoolSize;
    qDebug() << "  点列表对象:" << m_stats.pointListPoolSize;
    qDebug() << "  JSON对象:" << m_stats.jsonObjectPoolSize;
}

RenderReadyGameData* GameDataPool::acquireGameData()
{
    QMutexLocker locker(&m_gameDataMutex);
    
    RenderReadyGameData* data = nullptr;
    
    if (!m_gameDataPool.isEmpty()) {
        // 从池中获取
        data = m_gameDataPool.dequeue();
        {
            QMutexLocker statsLocker(&m_statsMutex);
            m_stats.gameDataPoolSize--;
        }
    } else {
        // 池为空，创建新对象
        data = new RenderReadyGameData();
        {
            QMutexLocker statsLocker(&m_statsMutex);
            m_stats.gameDataCreated++;
        }
        qDebug() << "GameDataPool: 池为空，创建新的游戏数据对象";
    }
    
    // 重置对象状态
    resetGameData(data);
    
    {
        QMutexLocker statsLocker(&m_statsMutex);
        m_stats.gameDataAcquired++;
    }
    
    return data;
}

void GameDataPool::releaseGameData(RenderReadyGameData* data)
{
    if (!data) {
        return;
    }
    
    QMutexLocker locker(&m_gameDataMutex);
    
    if (m_gameDataPool.size() < MAX_GAME_DATA_POOL_SIZE) {
        // 放回池中
        m_gameDataPool.enqueue(data);
        {
            QMutexLocker statsLocker(&m_statsMutex);
            m_stats.gameDataPoolSize++;
            m_stats.gameDataReleased++;
        }
    } else {
        // 池已满，直接删除
        delete data;
        {
            QMutexLocker statsLocker(&m_statsMutex);
            m_stats.gameDataReleased++;
        }
        qDebug() << "GameDataPool: 池已满，删除游戏数据对象";
    }
}

QList<QPoint>* GameDataPool::acquirePointList()
{
    QMutexLocker locker(&m_pointListMutex);
    
    QList<QPoint>* list = nullptr;
    
    if (!m_pointListPool.isEmpty()) {
        list = m_pointListPool.dequeue();
        {
            QMutexLocker statsLocker(&m_statsMutex);
            m_stats.pointListPoolSize--;
        }
    } else {
        list = new QList<QPoint>();
        list->reserve(50);
        {
            QMutexLocker statsLocker(&m_statsMutex);
            m_stats.pointListCreated++;
        }
    }
    
    resetPointList(list);
    
    {
        QMutexLocker statsLocker(&m_statsMutex);
        m_stats.pointListAcquired++;
    }
    
    return list;
}

void GameDataPool::releasePointList(QList<QPoint>* list)
{
    if (!list) {
        return;
    }
    
    QMutexLocker locker(&m_pointListMutex);
    
    if (m_pointListPool.size() < MAX_POINT_LIST_POOL_SIZE) {
        m_pointListPool.enqueue(list);
        {
            QMutexLocker statsLocker(&m_statsMutex);
            m_stats.pointListPoolSize++;
            m_stats.pointListReleased++;
        }
    } else {
        delete list;
        {
            QMutexLocker statsLocker(&m_statsMutex);
            m_stats.pointListReleased++;
        }
    }
}

QJsonObject* GameDataPool::acquireJsonObject()
{
    QMutexLocker locker(&m_jsonObjectMutex);
    
    QJsonObject* obj = nullptr;
    
    if (!m_jsonObjectPool.isEmpty()) {
        obj = m_jsonObjectPool.dequeue();
        {
            QMutexLocker statsLocker(&m_statsMutex);
            m_stats.jsonObjectPoolSize--;
        }
    } else {
        obj = new QJsonObject();
        {
            QMutexLocker statsLocker(&m_statsMutex);
            m_stats.jsonObjectCreated++;
        }
    }
    
    resetJsonObject(obj);
    
    {
        QMutexLocker statsLocker(&m_statsMutex);
        m_stats.jsonObjectAcquired++;
    }
    
    return obj;
}

void GameDataPool::releaseJsonObject(QJsonObject* obj)
{
    if (!obj) {
        return;
    }
    
    QMutexLocker locker(&m_jsonObjectMutex);
    
    if (m_jsonObjectPool.size() < MAX_JSON_OBJECT_POOL_SIZE) {
        m_jsonObjectPool.enqueue(obj);
        {
            QMutexLocker statsLocker(&m_statsMutex);
            m_stats.jsonObjectPoolSize++;
            m_stats.jsonObjectReleased++;
        }
    } else {
        delete obj;
        {
            QMutexLocker statsLocker(&m_statsMutex);
            m_stats.jsonObjectReleased++;
        }
    }
}

void GameDataPool::resetGameData(RenderReadyGameData* data)
{
    if (!data) return;

    data->snakeBody.clear();
    data->foods.clear();
    data->score = 0;
    data->direction = 3;
    data->alive = true;
    data->playerId.clear();
    data->timestamp = 0;
    data->sequenceNumber = 0;       // 重置序列号
    data->isValid = false;
    data->alivePlayers = 0;
    data->totalPlayers = 0;
    data->gameSpeed = 200;
    data->mapWidth = 40;
    data->mapHeight = 30;
    data->enableWalls = true;       // 重置墙壁设置
    data->obstacles.clear();        // 清空障碍物
}

void GameDataPool::resetPointList(QList<QPoint>* list)
{
    if (!list) return;
    
    list->clear(); // 清空内容但保留容量
}

void GameDataPool::resetJsonObject(QJsonObject* obj)
{
    if (!obj) return;
    
    *obj = QJsonObject(); // 重置为空对象
}

void GameDataPool::updateMemoryEstimate()
{
    QMutexLocker locker(&m_statsMutex);
    
    m_stats.estimatedMemoryUsage = 
        (m_stats.gameDataPoolSize + m_stats.gameDataCreated) * GAME_DATA_SIZE +
        (m_stats.pointListPoolSize + m_stats.pointListCreated) * POINT_LIST_SIZE +
        (m_stats.jsonObjectPoolSize + m_stats.jsonObjectCreated) * JSON_OBJECT_SIZE;
    
    // 计算内存减少比例（假设没有对象池时每次都要分配新对象）
    int totalOperations = m_stats.gameDataAcquired + m_stats.pointListAcquired + m_stats.jsonObjectAcquired;
    if (totalOperations > 0) {
        int reuseOperations = m_stats.gameDataReleased + m_stats.pointListReleased + m_stats.jsonObjectReleased;
        m_stats.memoryReductionRatio = double(reuseOperations) / totalOperations * 100;
    }
}

void GameDataPool::cleanup()
{
    qDebug() << "GameDataPool: 开始清理未使用的对象";

    int cleanedCount = 0;

    // 清理游戏数据池（保留最小数量）
    {
        QMutexLocker locker(&m_gameDataMutex);
        while (m_gameDataPool.size() > INITIAL_POOL_SIZE) {
            RenderReadyGameData* data = m_gameDataPool.dequeue();
            delete data;
            cleanedCount++;
            {
                QMutexLocker statsLocker(&m_statsMutex);
                m_stats.gameDataPoolSize--;
            }
        }
    }

    // 清理点列表池
    {
        QMutexLocker locker(&m_pointListMutex);
        while (m_pointListPool.size() > INITIAL_POOL_SIZE) {
            QList<QPoint>* list = m_pointListPool.dequeue();
            delete list;
            cleanedCount++;
            {
                QMutexLocker statsLocker(&m_statsMutex);
                m_stats.pointListPoolSize--;
            }
        }
    }

    // 清理JSON对象池
    {
        QMutexLocker locker(&m_jsonObjectMutex);
        while (m_jsonObjectPool.size() > INITIAL_POOL_SIZE) {
            QJsonObject* obj = m_jsonObjectPool.dequeue();
            delete obj;
            cleanedCount++;
            {
                QMutexLocker statsLocker(&m_statsMutex);
                m_stats.jsonObjectPoolSize--;
            }
        }
    }

    updateMemoryEstimate();

    qDebug() << "GameDataPool: 清理完成，清理了" << cleanedCount << "个对象";
}

void GameDataPool::warmup(int gameDataCount, int pointListCount, int jsonObjectCount)
{
    qDebug() << "GameDataPool: 开始预热对象池";
    qDebug() << "  游戏数据对象:" << gameDataCount;
    qDebug() << "  点列表对象:" << pointListCount;
    qDebug() << "  JSON对象:" << jsonObjectCount;

    // 预热游戏数据池
    {
        QMutexLocker locker(&m_gameDataMutex);
        while (m_gameDataPool.size() < gameDataCount && m_gameDataPool.size() < MAX_GAME_DATA_POOL_SIZE) {
            RenderReadyGameData* data = new RenderReadyGameData();
            m_gameDataPool.enqueue(data);
            {
                QMutexLocker statsLocker(&m_statsMutex);
                m_stats.gameDataPoolSize++;
                m_stats.gameDataCreated++;
            }
        }
    }

    // 预热点列表池
    {
        QMutexLocker locker(&m_pointListMutex);
        while (m_pointListPool.size() < pointListCount && m_pointListPool.size() < MAX_POINT_LIST_POOL_SIZE) {
            QList<QPoint>* list = new QList<QPoint>();
            list->reserve(50);
            m_pointListPool.enqueue(list);
            {
                QMutexLocker statsLocker(&m_statsMutex);
                m_stats.pointListPoolSize++;
                m_stats.pointListCreated++;
            }
        }
    }

    // 预热JSON对象池
    {
        QMutexLocker locker(&m_jsonObjectMutex);
        while (m_jsonObjectPool.size() < jsonObjectCount && m_jsonObjectPool.size() < MAX_JSON_OBJECT_POOL_SIZE) {
            QJsonObject* obj = new QJsonObject();
            m_jsonObjectPool.enqueue(obj);
            {
                QMutexLocker statsLocker(&m_statsMutex);
                m_stats.jsonObjectPoolSize++;
                m_stats.jsonObjectCreated++;
            }
        }
    }

    updateMemoryEstimate();

    qDebug() << "GameDataPool: 预热完成";
}

void GameDataPool::cleanupPools()
{
    qDebug() << "GameDataPool: 清理所有对象池";

    // 清理游戏数据池
    {
        QMutexLocker locker(&m_gameDataMutex);
        while (!m_gameDataPool.isEmpty()) {
            RenderReadyGameData* data = m_gameDataPool.dequeue();
            delete data;
        }
    }

    // 清理点列表池
    {
        QMutexLocker locker(&m_pointListMutex);
        while (!m_pointListPool.isEmpty()) {
            QList<QPoint>* list = m_pointListPool.dequeue();
            delete list;
        }
    }

    // 清理JSON对象池
    {
        QMutexLocker locker(&m_jsonObjectMutex);
        while (!m_jsonObjectPool.isEmpty()) {
            QJsonObject* obj = m_jsonObjectPool.dequeue();
            delete obj;
        }
    }

    qDebug() << "GameDataPool: 所有对象池已清理";
}

void GameDataPool::onCleanupTimer()
{
    cleanup();
}

void GameDataPool::onStatsTimer()
{
    updateMemoryEstimate();

    QMutexLocker locker(&m_statsMutex);
    emit statsUpdated(m_stats);
}

GameDataPool::PoolStats GameDataPool::getStats() const
{
    QMutexLocker locker(&m_statsMutex);
    return m_stats;
}

void GameDataPool::printStats() const
{
    QMutexLocker locker(&m_statsMutex);

    qDebug() << "=== GameDataPool 统计信息 ===";
    qDebug() << "游戏数据池:";
    qDebug() << "  池大小:" << m_stats.gameDataPoolSize;
    qDebug() << "  获取次数:" << m_stats.gameDataAcquired;
    qDebug() << "  释放次数:" << m_stats.gameDataReleased;
    qDebug() << "  创建次数:" << m_stats.gameDataCreated;

    qDebug() << "点列表池:";
    qDebug() << "  池大小:" << m_stats.pointListPoolSize;
    qDebug() << "  获取次数:" << m_stats.pointListAcquired;
    qDebug() << "  释放次数:" << m_stats.pointListReleased;
    qDebug() << "  创建次数:" << m_stats.pointListCreated;

    qDebug() << "JSON对象池:";
    qDebug() << "  池大小:" << m_stats.jsonObjectPoolSize;
    qDebug() << "  获取次数:" << m_stats.jsonObjectAcquired;
    qDebug() << "  释放次数:" << m_stats.jsonObjectReleased;
    qDebug() << "  创建次数:" << m_stats.jsonObjectCreated;

    qDebug() << "内存使用:";
    qDebug() << "  估算内存使用:" << m_stats.estimatedMemoryUsage << "字节";
    qDebug() << "  内存减少比例:" << QString::number(m_stats.memoryReductionRatio, 'f', 1) << "%";

    // 计算复用率
    if (m_stats.gameDataAcquired > 0) {
        double gameDataReuse = double(m_stats.gameDataReleased) / m_stats.gameDataAcquired * 100;
        qDebug() << "  游戏数据复用率:" << QString::number(gameDataReuse, 'f', 1) << "%";
    }

    if (m_stats.pointListAcquired > 0) {
        double pointListReuse = double(m_stats.pointListReleased) / m_stats.pointListAcquired * 100;
        qDebug() << "  点列表复用率:" << QString::number(pointListReuse, 'f', 1) << "%";
    }

    if (m_stats.jsonObjectAcquired > 0) {
        double jsonObjectReuse = double(m_stats.jsonObjectReleased) / m_stats.jsonObjectAcquired * 100;
        qDebug() << "  JSON对象复用率:" << QString::number(jsonObjectReuse, 'f', 1) << "%";
    }
}
